#pragma once

#include "comutil.h"
#include "comdef.h"

#include "FunctionDispatch.h"
#include "I_GlobalFunction.h"

void CreateFunDispInstance(IWebBrowser2* pBrowser, IDispatch** ppDisp, PGFINIT pInit);
_variant_t ExecuteDispatch(IDispatch* pFun, IDispatch* pParam);
_variant_t ExecuteScript(IWebBrowser2* pBrowser, LPCTSTR lpszFunName, IDispatch* pDispParam);
_variant_t ExecuteScript(IWebBrowser2* pBrowser, LPCTSTR lpszFunName, _variant_t& vParam);
_variant_t EvalScript(IWebBrowser2* pBrowser, BSTR bstrCode, BSTR bstrLanguage = CComBSTR("javascript"));

struct GFSTRINGFUNCTION_bstr_t
{
	static WCHAR* OnAllocBuffer (PGFSTRING pString, UINT nLen)
	{
		WCHAR* pRet = new WCHAR[nLen+1];
		pRet[nLen] = 0;
		return pRet;
	}
	static void OnReleaseBuffer (PGFSTRING pString, WCHAR* pBuf)
	{
		OnSetString(pString, pBuf);
		delete [] pBuf;
	}
	static void OnSetString (PGFSTRING pString, LPCWSTR szSrc)
	{
		_bstr_t* p = (_bstr_t*)pString->pContext;
		*p = szSrc;
	}
};
struct GFSTRINGFUNCTION_variant_t
{
	static WCHAR* OnAllocBuffer (PGFSTRING pString, UINT nLen)
	{
		WCHAR* pRet = new WCHAR[nLen+1];
		pRet[nLen] = 0;
		return pRet;
	}
	static void OnReleaseBuffer (PGFSTRING pString, WCHAR* pBuf)
	{
		OnSetString(pString, pBuf);
		delete [] pBuf;
	}
	static void OnSetString (PGFSTRING pString, LPCWSTR szSrc)
	{
		_variant_t* p = (_variant_t*)pString->pContext;
		p->Clear();
		p->vt = VT_BSTR;
		p->bstrVal = ::SysAllocString(szSrc);
	}
};

class CZAFunctionDispatch : public CFunctionDispatch
{
public:
	CZAFunctionDispatch(IWebBrowser2* pBrowser, PGFINIT pInit);
	
private:
	static _variant_t JSGlobal_CreateSession (IWebBrowser2* pBrowser, IDispatch* pDisp, void* pParam);
	static _variant_t JSGlobal_PostUrl (IWebBrowser2* pBrowser, IDispatch* pDisp, void* pParam);
	static _variant_t JSGlobal_GetUrl (IWebBrowser2* pBrowser, IDispatch* pDisp, void* pParam);

	static _variant_t JSGlobal_GetGlobalValue (IWebBrowser2* pBrowser, IDispatch* pDisp, void* pParam);
	static _variant_t JSGlobal_SetGlobalValue (IWebBrowser2* pBrowser, IDispatch* pDisp, void* pParam);
	static _variant_t JSGlobal_SaveGlobalValue (IWebBrowser2* pBrowser, IDispatch* pDisp, void* pParam);

	static _variant_t JSGlobal_AddLog (IWebBrowser2* pBrowser, IDispatch* pDisp, void* pParam);

private:
	std::auto_ptr<I_GlobalFunction> m_spFun;
};